Skip to content

Feat/lint#4

Merged
kooksee merged 3 commits intomasterfrom
feat/lint
Jan 1, 2026
Merged

Feat/lint#4
kooksee merged 3 commits intomasterfrom
feat/lint

Conversation

@kooksee
Copy link
Copy Markdown
Contributor

@kooksee kooksee commented Jan 1, 2026

No description provided.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @kooksee, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request represents a major overhaul and rebranding of the project, transitioning from 'SwaGin' to 'OpenDoc'. The core focus is on enhancing the Go OpenAPI documentation generation capabilities, making it more robust, maintainable, and aligned with modern Go practices. Key changes include the integration of golangci-lint for improved code quality, a complete rewrite of the project documentation, and significant refactoring of the internal OpenAPI schema generation logic, including the adoption of Go 1.18's any keyword and comprehensive unit testing for utility functions.

Highlights

  • Linting Configuration: A new .golangci.yaml file has been added to configure golangci-lint. This includes enabling the govet linter, specifying exclusions for certain paths, and configuring formatters like goimports, gofmt, and gofumpt with specific settings and rewrite rules (e.g., interface{} to any).
  • Project Renaming and Documentation Update: The project has been rebranded from 'SwaGin' to 'OpenDoc'. The README.md has been completely rewritten in Chinese to reflect this change, detailing the new project's introduction, features, installation, quick start guide, core concepts, parameter mapping, utility methods, HTTP framework integration, documentation templates, and build/run instructions.
  • Build System Enhancements: The Makefile has been updated to include new targets: refactor for applying gofumpt formatting and lint for running golangci-lint, streamlining code quality checks and formatting.
  • Go 1.18+ any Keyword Adoption: Across several opendoc package files (aaa.go, operation.go, util.go), interface{} has been replaced with the any keyword, leveraging Go 1.18+ features for improved readability and conciseness.
  • OpenAPI Schema Generation Improvements: The opendoc/util.go file has received significant updates to its schema generation logic. This includes enhanced handling for map types to correctly generate AdditionalProperties, improved determination of Required status for struct fields and parameters based on required and omitempty tags, and ensuring path parameters are always marked as required. A new IsRequired helper function was also added.
  • API Model and Example Updates: The example API models and application logic in internal/examples/main.go have been refactored and updated to align with the new opendoc package structure. The old internal/examples/api.go file has been removed. The internal/examples/openapi.yaml reflects these changes in its schema definitions and path operations.
  • New Getter Methods for OpenAPI Objects: New getter methods have been added to opendoc/operation.go (e.g., GetPath, GetMethod, GetOperationID) and opendoc/service.go (e.g., GetOperations, GetPath, GetName) to provide easier programmatic access to OpenAPI object properties.
  • Comprehensive Unit Tests for Utilities: A new test file, opendoc/util_test.go, has been added, providing extensive unit tests for the utility functions in opendoc/util.go. This significantly improves test coverage and ensures the correctness of schema and parameter generation logic.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/ci.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@kooksee kooksee merged commit 4055f32 into master Jan 1, 2026
1 check passed
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

你好,感谢你对项目的贡献。这次的 Pull Request 引入了 linting 工具,并对 OpenAPI 文档生成功能进行了大量的重构和改进,包括更新了 README 文档,这是一个非常棒的进步。我发现了一些可以改进的地方,主要集中在 linting 配置的增强、一个关键的文档生成 bug、以及一些代码的健壮性和可读性方面。请查看我的具体评论。

Comment on lines +91 to +92
lo.Must0(os.WriteFile("./internal/examples/openapi.yaml",
lo.Must(yaml.Marshal(lo.Must(doc.BuildSwagger().MarshalYAML()))), 0644))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

你好,这部分写入 openapi.yaml 文件的逻辑似乎有问题。
doc.MarshalYAML() 会返回一个 []byte 类型的 YAML 数据。你再对这个 []byte 使用 yaml.Marshal,会导致对一个已经是 YAML 格式的字节切片再次进行 YAML 编码,结果通常是一个 Base64 编码的字符串,而不是预期的 YAML 文件内容。

之前的写法是正确的。我建议恢复之前的写法,或者使用更简洁的方式。这个 bug 会导致生成的 openapi.yaml 文件内容不正确,从而影响文档的可用性。

Suggested change
lo.Must0(os.WriteFile("./internal/examples/openapi.yaml",
lo.Must(yaml.Marshal(lo.Must(doc.BuildSwagger().MarshalYAML()))), 0644))
data, err := doc.MarshalYAML()
lo.Must0(err)
lo.Must0(os.WriteFile("./internal/examples/openapi.yaml", data, 0644))

Comment on lines 363 to 394
getTag(tags, queryTag, func(tag *structtag.Tag) {
parameter = openapi3.NewQueryParameter(tag.Name)
if !tag.HasOption(omitempty) {
// Check required tag first, then fallback to omitempty
requiredTag, _ := tags.Get(required)
if requiredTag != nil && requiredTag.Name == "true" {
parameter.Required = true
} else if !tag.HasOption(omitempty) {
parameter.Required = true
}
})

getTag(tags, headerTag, func(tag *structtag.Tag) {
parameter = openapi3.NewHeaderParameter(tag.Name)
if !tag.HasOption(omitempty) {
// Check required tag first, then fallback to omitempty
requiredTag, _ := tags.Get(required)
if requiredTag != nil && requiredTag.Name == "true" {
parameter.Required = true
} else if !tag.HasOption(omitempty) {
parameter.Required = true
}
})

getTag(tags, cookieTag, func(tag *structtag.Tag) {
parameter = openapi3.NewCookieParameter(tag.Name)
if !tag.HasOption(omitempty) {
// Check required tag first, then fallback to omitempty
requiredTag, _ := tags.Get(required)
if requiredTag != nil && requiredTag.Name == "true" {
parameter.Required = true
} else if !tag.HasOption(omitempty) {
parameter.Required = true
}
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

你好,这部分用于判断参数是否必需(required)的逻辑存在一些问题:

  1. 逻辑重复queryTag, headerTag, cookieTag 的处理逻辑几乎完全一样,导致了代码重复。建议将这部分逻辑提取到一个辅助函数中。
  2. 逻辑错误else if !tag.HasOption(omitempty) 这部分判断是错误的。这里的 tagquery, headercookie 标签,它们通常不像 json 标签那样有 omitempty 选项。这个逻辑可能是从处理 json 标签的代码中复制过来的,但在这里不适用,可能会导致参数被错误地标记为必需。

参数是否必需的正确逻辑应该是:

  • 路径参数(pathuri)总是必需的。
  • 其他类型的参数(query, header, cookie)当且仅当它们有 required:"true" 标签时才是必需的。

我建议移除 !tag.HasOption(omitempty) 的判断,并重构这部分代码以消除重复。这个错误可能会导致 API 规范与实际行为不符,影响客户端的生成和使用。

Comment on lines +6 to +7
enable:
- govet
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

你好,感谢你添加了 golangci-lint 的支持!这是一个很好的改进。
不过,目前只启用了 govet 这一个 linter。为了更好地保证代码质量和发现潜在问题,我建议启用更多有用的 linter。例如:

  • staticcheck: 一个强大的静态分析工具集,可以发现很多细微的 bug。
  • unused: 检查未使用的代码。
  • ineffassign: 检查未使用的变量赋值。
  • errcheck: 检查未处理的 error 返回值。
  • gofumpt: 确保代码格式一致。

启用这些 linter 可以帮助我们更早地发现问题,提升代码的健壮性。

  enable:
    - govet
    - staticcheck
    - unused
    - ineffassign
    - errcheck
    - gofumpt

Comment on lines +246 to +251
getTag(tags, required, func(_ *structtag.Tag) {
if _t, err := tags.Get(required); err == nil && _t.Name == "true" {
// Mark as required by removing AllowEmptyValue
fieldSchema.AllowEmptyValue = false
}
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

你好,这部分处理 required 标签的逻辑可以简化。
getTag 的回调函数只有在找到标签时才会执行,所以在回调内部再次调用 tags.Get(required) 是多余的。可以直接使用回调函数传入的 tag 参数,这样代码会更简洁易读。

Suggested change
getTag(tags, required, func(_ *structtag.Tag) {
if _t, err := tags.Get(required); err == nil && _t.Name == "true" {
// Mark as required by removing AllowEmptyValue
fieldSchema.AllowEmptyValue = false
}
})
getTag(tags, required, func(tag *structtag.Tag) {
if tag.Name == "true" {
// Mark as required by removing AllowEmptyValue
fieldSchema.AllowEmptyValue = false
}
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant